import { history } from '@/router'
import store from '@/store'
import { ApiResponse } from '@/types/data'
import { RootAction } from '@/types/store'
import { Toast } from 'antd-mobile'
import axios, { AxiosError } from 'axios'

import { getToken, removeToken, setToken } from './token'

const baseURL = 'http://geek.itheima.net/v1_0/'
// 备用
// const baseURL = 'http://toutiao.itheima.net/v1_0/'

// 创建实例
const http = axios.create({
  baseURL, // 基地址
  timeout: 5000,
})

// 添加请求拦截器
http.interceptors.request.use(
  (config) => {
    // 统一添加token
    const tokenObj = getToken() // {}
    if (tokenObj.token) {
      config.headers!.Authorization = 'Bearer ' + tokenObj.token
    }

    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)

// 添加响应拦截器
http.interceptors.response.use(
  (response) => {
    return response
  },
  async (error: AxiosError<ApiResponse>) => {
    // 一旦响应失败， 就是给错误提示
    // console.log(error, 999)
    if (!error.response) {
      // 服务器崩、网络崩
      Toast.show('服务器繁忙， 请稍后再试')
      return Promise.reject(error)
    }

    // --------------------token无感刷新--------------------
    // console.log(error.response, 888)
    if (error.response.status === 401) {
      // token有问题
      const tokenObj = getToken()
      if (tokenObj.token) {
        try {
          // token过期了
          // 1.刷新token是需要带着refresh_token去发请求的！！必须使用原生axios
          const res = await axios.put<ApiResponse<{ token: string }>>(
            baseURL + 'authorizations',
            null,
            {
              headers: {
                Authorization: 'Bearer ' + tokenObj.refresh_token,
              },
            }
          )
          // console.log(res, 7777)
          // res.data.data.token ==>> 新的 主token ==>> 2.组装成tokenObj
          const newTokenObj = {
            token: res.data.data.token,
            refresh_token: tokenObj.refresh_token,
          }

          // 3.存入仓库 存入本地
          setToken(newTokenObj)
          // useDispatch()
          store.dispatch({
            type: 'login/login',
            payload: newTokenObj,
          } as RootAction)

          // 4.原来的事得做完， 失败的请求重新发 =》 无感
          // http.get('/user')
          // http({
          //   method: 'get',
          //   url: '/user'
          // })
          // error.config => 就有之前出错的请求的所有配置
          return http(error.config)
        } catch (e) {
          // 表示refresh_token也过期了。。
          // 清除错误的token
          removeToken()
          store.dispatch({
            type: 'login/login',
            payload: {},
          } as RootAction)

          // 回到登录页
          history.push({
            pathname: '/login',
            state: {
              from: history.location.pathname, // 回跳地址
            },
          })
        }
      } else {
        // 未登录
        // history.push
        history.push('/login')
      }
    }

    // --------------------token无感刷新--------------------

    // 直接获取后端给的文字 做提示
    Toast.show(error.response.data.message)

    return Promise.reject(error)
  }
)

export default http
